package com.mock.ems.redis;

import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPubSub;
import redis.clients.jedis.Tuple;

import java.util.List;
import java.util.Set;

public class RedisSingleHandler implements RedisHandler {
	
	private static JedisPool pool;
	
	private static final Logger logger = LoggerFactory.getLogger(RedisHandler.class);
	
	public Long zadd(String key,Double score,String member) {
		try (Jedis client = pool.getResource()) {
			return client.zadd(key, score, member);
		}
	}
	
	public Long zrem(String key,String member) {
		try (Jedis client = pool.getResource()) {
			return client.zrem(key, member);
		}
		//return redisCluster.zadd(key, score, member);
	}
	
	public void zremrangeByRank(String key,Long start,Long end) {
		try (Jedis client = pool.getResource()) {
			client.zremrangeByRank(key, start, end);
		}
		//redisCluster.zremrangeByRank(key, start, end);
	}
	
	public void zincrby(String key,Double score,String member) {
		try (Jedis client = pool.getResource()) {
			client.zincrby(key, score, member);
		}
		//redisCluster.zincrby(key, score, member);
	}
	
	public Long zcard(String key) {
		try (Jedis client = pool.getResource()) {
			return client.zcard(key);
		}
	}
	
	public Set<String> zrange(String key,Long start,Long end) {
		try (Jedis client = pool.getResource()) {
			return client.zrange(key, start, end);
		}
	}
	
	public Set<String> zrevrange(String key,Long start,Long end) {
		try (Jedis client = pool.getResource()) {
			return client.zrevrange(key, start, end);
		}
	}
	
	public Long zrank(String key,String member) {
		try (Jedis client = pool.getResource()) {
			return client.zrank(key, member);
		}
	}
	
	public Long zrevrank(String key,String member) {
		try (Jedis client = pool.getResource()) {
			return client.zrevrank(key, member);
		}
	}
	
	/** 
	* @Title: zrevrangeWithScores 
	* @Description: 获取ZSET中的Score和Member
	* @param key
	* @param start
	* @param end
	* @return Set<Tuple>
	* @throws 
	*/
	public Set<Tuple> zrevrangeWithScores(String key,Long start,Long end) {
		try (Jedis client = pool.getResource()) {
			return client.zrevrangeWithScores(key, start, end);
		}
	}
	
	public Double zscore(String key,String member) {
		try (Jedis client = pool.getResource()) {
			return client.zscore(key, member);
		}
	}
	
	public Long zrem(String key, String... member){
		try (Jedis client = pool.getResource()) {
			return client.zrem(key, member);
		}
	}
	
	
	public boolean set(String key,Object val) {
		try (Jedis client = pool.getResource()) {
			String statusCode = client.set(key, JSON.toJSONString(val));
			return statusCode.equals("OK");
		}
	}
	
	public boolean del(String key) {
		try (Jedis client = pool.getResource()) {
			return client.del(key) > 0;
		}
	}
	
	public Boolean set(String key,String val,Integer timeToLive) {
		try (Jedis client = pool.getResource()) {
			String statusCode = client.set(key, val);
			Long expired = client.expire(key, timeToLive);
			return statusCode.equals("OK") && expired == 1;
		}
	}
	
	public Boolean set(String key,Object val,Integer timeToLive) {
		try (Jedis client = pool.getResource()) {
			String statusCode = client.set(key, JSON.toJSONString(val));
			Long expired = client.expire(key, timeToLive);
			return statusCode.equals("OK") && expired == 1;
		}
	}
	
	public <T> T get(String key,Class<T> clazz) {
		try (Jedis client = pool.getResource()) {
			String value = client.get(key);
			if (null == value) return null;
			return JSON.parseObject(value, clazz);
		}catch (Exception e) {
			logger.error(e.getMessage(), e);
			return null;
		}
	}
	
	public Long incr(String key ,Long offset) {
		try (Jedis client = pool.getResource()) {
			return client.incrBy(key, offset);
		}
	}
	
	public Long decr(String key ,Long offset) {
		try (Jedis client = pool.getResource()) {
			return client.decrBy(key, offset);
		}
	}
	
	public Long ttl(String key) {
		try (Jedis client = pool.getResource()) {
			return client.ttl(key);
		}
	}
	
	public boolean expiredAt(String key,Long unixTime) {
		try (Jedis client = pool.getResource()) {
			return client.expireAt(key, unixTime) > 1;
		}
	}
	
	public boolean expired(String key,Integer timeToLive) {
		try (Jedis client = pool.getResource()) {
			return client.expire(key, timeToLive) > 0;
		}
	}
		
	public Long rpush(String key,String ...elements) {
		try (Jedis client = pool.getResource()) {
			return client.rpush(key, elements);
		}
	}
	
	public List<String> lrange(String key,Long start,Long end) {
		try (Jedis client = pool.getResource()) {
			return client.lrange(key, start, end);
		}
	}
	
	public Long lrem(String key, String element){
		try (Jedis client = pool.getResource()) {
			return client.lrem(key, 1L, element);
		}
	}
	
	public boolean setnx(String key,String value) {
		try (Jedis client = pool.getResource()) {
			return client.setnx(key, value) == 1;
		}
	}
	
	public boolean hset(String key,String field,String value) {
		try (Jedis client = pool.getResource()) {
			Long result = client.hset(key, field, value);
			return (result == 0 || result ==  1);
		}
	}
	
	public Long hincrby(String key,String field,Long value) {
		try (Jedis client = pool.getResource()) {
			return client.hincrBy(key, field, value);
		}
	}
	
	public Double hincrbyfloat(String key,String field,Double value) {
		try (Jedis client = pool.getResource()) {
			return client.hincrByFloat(key, field, value);
		}
	}
	
	public boolean hdel(String key,String ...fields) {
		try (Jedis client = pool.getResource()) {
			Long result = client.hdel(key, fields);
			return (result > 0);
		}		
	}
	
	public String hget(String key,String field) {
		try (Jedis client = pool.getResource()) {
			return client.hget(key, field);
		}
	}
	
	public List<String> hmget(String key,String ...fields) {
		try (Jedis client = pool.getResource()) {
			return client.hmget(key, fields);
		}
	}
	
	public Set<String> hkeys(String key) {
		try (Jedis client = pool.getResource()) {
			return client.hkeys(key);
		}
	}
	
	public List<String> hvals(String key) {
		try (Jedis client = pool.getResource()) {
			return client.hvals(key);
		}
	}
	
	public Long publish(String channel,String message) {
		try (Jedis client = pool.getResource()) {
			return client.publish(channel, message);
		}
	}
	
	public List<String> blpop(int timeout,String key) {
		try (Jedis client = pool.getResource()) {
			return client.blpop(timeout, key);
		}
	}
	
	@Override
	public void subscribe(JedisPubSub jedisPubSub,String... channels) {
		try (Jedis client = pool.getResource()) {
			client.subscribe(jedisPubSub, channels);
		}
	}

	@Override
	public Double incrByFloat(String key, Double value) {
		try (Jedis client = pool.getResource()) {
			return client.incrByFloat(key, value);
		}
	}

	@Override
	public Set<String> zrangeByScore(String key, double min, double max) {
		try (Jedis client = pool.getResource()) {
			return client.zrangeByScore(key,min,max);
		}
	}
}
